package com.tongji.diy.model.furniturePlacementOptimization
{
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.Bedding;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.BeddingNearby;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.Facal;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FacalCompound;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FacalContainee;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FacalContainer;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FurnitureBase;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.NearBase;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.Seat;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.SeatNearby;
	import com.tongji.diy.utils.OptimizationMath;
	import com.tongji.diy.utils.PolygonMath;
	import com.tongji.diy.view.component3D.Furniture;
	
	import flash.geom.Point;
	
	import de.polygonal.ds.DListNode;

	//该类负责初始化各种列表
	public class ConstructorBuilder
	{
		private var data:DataAndFunction;
		private var EXPAND_COEFFICIENT:Number = 1.8;
		public function ConstructorBuilder(data:DataAndFunction)
		{
			this.data = data;
			main();
		}
		
		private function main():void
		{
			classify();
			data._aganistWallList = buildAnganistWallList();
			analysisRoom();
			analysisList();
			setNearbyWeight();
			setSLWeight();
			//test();
		}
		
		private function test():void
		{
			var triangle:Vector.<Point>  = new Vector.<Point>;
			triangle.push(new Point(10,10),new Point(5,20),new Point(15,20));
			var rectangle:Vector.<Point> = new Vector.<Point>;
			rectangle.push(new Point(4,-12),new Point(22,-12), new Point(22,4),new Point(4,4));
		//data.perpareTriangle(triangle);
			//trace(data.triangleRectangleCollision(rectangle));
			//trace(PolygonMath.triangleIntersecRectangle(triangle,rectangle));
		}
		
		private function analysisList():void
		{
			OptimizationMath.assert(!(data._beddingList.length  && data._seatList.length));
			OptimizationMath.assert(!(data._seatNearbyList.length  && data._beddingNearbyList.length));
			//存在bedding
			if(data._beddingList.length)
				data.beddingSign = true;
			//存在seat
			if(data._seatList.length)
				data.seatSign = true;
			
			if(data._seatNearbyList.length)
				var nearbyList:Vector.<NearBase> = data._seatNearbyList;
			else
				nearbyList = data._beddingNearbyList;
			//存在对称nearby家具
			var tempV:Vector.<Boolean> = new Vector.<Boolean>();
			for(var i:int = 0; i < nearbyList.length; ++i)
			{
				tempV.push(false);
			}
			
			for(i = 0; i < nearbyList.length; ++i)
			{
				for(var j:int = i+1; j < nearbyList.length; ++j)
				{
					if(!tempV[i]&&!tempV[j]&&nearbyList[i].furnitureClass == nearbyList[j].furnitureClass)
					{
						var tempV2:Vector.<NearBase> = new Vector.<NearBase>;
						tempV2.push(nearbyList[i],nearbyList[j]);
						data.symetryList.push(tempV2);
						tempV[i] = true;
						tempV[j] = true;
						data.symetrySign = true;
					}
				}
			}
			//家具可见性测试
			var minHeight:Number = Infinity;
			var slList:Vector.<FurnitureBase>;
			if(data._beddingList.length)
			{
				slList = data._beddingList;
			}
			else
			{
				slList = data._seatList;
			}
			for(i = 0; i < slList.length; ++i)
			{
				if(minHeight > slList[i].height)
					minHeight = slList[i].height;
			}
			
			if(data._facalList.length)
			{
					if(data._facalList[0] is FacalCompound)
						minHeight = Math.min((data._facalList[0] as FacalCompound).container.height, minHeight);
					else if(data._facalList[0] is FacalContainer)
						minHeight = Math.min((data._facalList[0] as FacalContainer).height, minHeight);
					else if(data._facalList[0] is FacalContainee)
						minHeight = Math.min((data._facalList[0] as FacalContainee).height, minHeight);
			}
			
			for(i = 0; i < nearbyList.length; ++i)
			{
				if(nearbyList[i].height > minHeight)
				{
					data.visibleSign = true;
					data.visibleList.push(nearbyList[i]);
				}
			}
			
		}
		
		private function setSLWeight():void
		{
			var SLlist:Vector.<FurnitureBase>;
			if(data._seatNearbyList && data._seatNearbyList.length)
				SLlist = data._seatList;
			if(data._beddingNearbyList && data._beddingNearbyList.length)
				SLlist = data._beddingList;
			
			if(SLlist)
			{
				SLlist.sort(sort);
				SLlist.forEach(forEach);
			}
			return;
			
			function sort(furA:FurnitureBase,furB:FurnitureBase):Number
			{
				if(furA.width*furA.length > furB.width*furB.length)
					return 1;
				return -1;
			}
			
			function forEach(item:FurnitureBase, index:int, v:*):void
			{
				OptimizationMath.assert(SLlist.length > 0);
				item.weight = item.width*item.length/(SLlist[SLlist.length - 1].width*SLlist[SLlist.length - 1].length);
				//item.weight = Math.pow(1.2, index);
				//count *= EXPAND_COEFFICIENT;
				//item.weight = -Math.pow( item.width*item.length/(SLlist[SLlist.length - 1].width*SLlist[SLlist.length - 1].length) - 1,4) + 1;
			}
		}
		
		private function setNearbyWeight():void
		{
			var nearbylist:Vector.<NearBase>;
			if(data._seatNearbyList && data._seatNearbyList.length)
				nearbylist = data._seatNearbyList;
			if(data._beddingNearbyList && data._beddingNearbyList.length)
				nearbylist = data._beddingNearbyList;
			
			if(nearbylist)
			{
				nearbylist.sort(sort);
				nearbylist.forEach(forEach);
			}
			return;
			
			function sort(furA:FurnitureBase,furB:FurnitureBase):Number
			{
				if(furA.width*furA.length > furB.width*furB.length)
					return 1;
				return -1;
			}
			
			function forEach(item:FurnitureBase, index:int, v:*):void
			{
				OptimizationMath.assert(nearbylist.length > 0);
				//item.weight = item.width*item.length/(nearbylist[nearbylist.length - 1].width*nearbylist[nearbylist.length - 1].length);
				//count *= EXPAND_COEFFICIENT;
				item.weight = -Math.pow( item.width*item.length/(nearbylist[nearbylist.length - 1].width*nearbylist[nearbylist.length - 1].length) - 1,4) + 1;
			}
		}
		
		private function classify():void
		{
			for(var i:int = 0; i < data._block.length; ++i)
			{
				var fur:FurnitureBase = data._block[i];
				if(fur is Facal)
				{
					data._facalList.push(fur);
				}
				else if(fur is Seat)
				{
					data._seatList.push(fur);
				}
				else if(fur is Bedding)
				{
					data._beddingList.push(fur);
				}
				else if(fur is BeddingNearby)
				{
					data._beddingNearbyList.push(fur);
				}
				else if(fur is SeatNearby)
				{
					data._seatNearbyList.push(fur);
				}
			}
		}
		
		
		
		
		private function buildAnganistWallList():Vector.<FurnitureBase>
		{
			var v:Vector.<FurnitureBase> = new Vector.<FurnitureBase>;
			for(var i:int = 0; i < data._block.length; i++)
			{
				if(data._block[i].anganistWall)
					v.push(data._block[i]);
			}
			
			v.sort(aganistWallSort);
			
			return v;
		
			//排序按照bedding > facal > 一般家具的顺序进行排序
			function aganistWallSort(A:FurnitureBase, B:FurnitureBase):int
			{
				if(A is Bedding)
					return -1;
				else if(B is Bedding)
					return 1;
				else if(A is Facal)
					return -1;
				else if(B is Facal)
					return 1;
				else if(A.length * A.width > B.length * B.width)
					return -1;
				else
					return 1;
			}
		}
		
		private function analysisRoom():void
		{
			var node:DListNode = data._room.roomPointList.head;
			while(1)
			{
				var orientedDriection:Point = new Point(node.next.data.globalX - node.data.globalX, node.next.data.globalY - node.data.globalY);
				if(orientedDriection.x * -1 < 0)
				{
					data._orientedSelectionList.push(Math.PI/2 - PolygonMath.vectorAngle(orientedDriection, new Point(0,-1)));
				}
				else
				{	
					data._orientedSelectionList.push(Math.PI/2 + PolygonMath.vectorAngle(orientedDriection, new Point(0,-1)));
				}
				var a:Number = node.next.data.globalX - node.data.globalX;
				var b:Number = node.next.data.globalY - node.data.globalY;
				data._roomSideLengthList.push(data._roomCircumference + Math.sqrt(a*a + b*b));
				data._roomCircumference = data._roomSideLengthList[data._roomSideLengthList.length-1];
				
				//通过叉积的方法找出指向房间内部且垂直于墙的方向向量
				var c:Number = node.next.next.data.globalX - node.next.data.globalX;
				var d:Number = node.next.next.data.globalY - node.next.data.globalY;
				
				if((a*a + b*b) * (a*d - c*b) > 0)
				{
					data._roomWallVerticalOrentationList.push(new Point(-b/Math.sqrt(a*a+b*b),a/Math.sqrt(a*a+b*b)));
				}
				else
				{
					data._roomWallVerticalOrentationList.push(new Point(b/Math.sqrt(a*a+b*b),-a/Math.sqrt(a*a+b*b)));
				}
				
				data._roomPoints.push(new Point(node.data.globalX, node.data.globalY));
				
				node = node.next;
				
				if(data._room.roomPointList.head == node)					
					break;
			}
			
			for(var i:int = 0; i < data._roomPoints.length; ++i)
				data._roomRandnums.push(data._roomSideLengthList[i] / data._roomCircumference);
		}
	
	}
}